﻿
using Newtonsoft.Json;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public static class GameData
{
    public static List<RoleData> listRoles;
    public static int _curRoleIndex;

    public static Dictionary<string, List<ItemData>> dicItems;
    public static RoleData _curRole => listRoles[_curRoleIndex];

    public static Dictionary<string, List<MissionData>> dicMissions;
    public static List<MissionData> _curMission => dicMissions[listRoles[_curRoleIndex].id];

    public static bool isItemChanged;
    public static bool isMissionChanged;
    public static bool isMissionProgressChanged;
    public static bool isDungeonChange;
    public static void Create(string roleId)
    {
        RoleInfo roleInfo = StaticData.GetRoleInfo(roleId);

        RoleData roleData = new RoleData()
        {
            id = Guid.NewGuid().ToString(),
            roleid = roleId,
            hp = roleInfo.hp,
            attack = roleInfo.attack,
            deface = roleInfo.defence,
            level = 1,
        };
        for (int i = 1; i < 4; i++)
        {
            roleData.equips[i] = "";
        }
        listRoles.Add(roleData);
        dicItems.Add(roleData.id, new List<ItemData>());
        dicMissions.Add(roleData.id, new List<MissionData>());
        isItemChanged = true;
    }

    static public RoleData GetCurRoleData()
    {
        return listRoles[_curRoleIndex];
    }
    public static void PassLevel()
    {
        listRoles[_curRoleIndex].dungeonLevel++;
        isDungeonChange = true;
    }

    public static void Save()
    {
        string json = JsonConvert.SerializeObject(listRoles);
        File.WriteAllText(Path.Combine(Application.persistentDataPath, "listRoles.json"), json);

        json = JsonConvert.SerializeObject(dicItems);
        File.WriteAllText(Path.Combine(Application.persistentDataPath, "dicItems.json"), json);

        json = JsonConvert.SerializeObject(dicMissions);
        File.WriteAllText(Path.Combine(Application.persistentDataPath, "dicMissions.json"), json);

    }

    public static void Load()
    {
        string filePath = Path.Combine(Application.persistentDataPath, "listRoles.json");

        if (File.Exists(filePath))
        {
            string json = File.ReadAllText(filePath);
            listRoles = JsonConvert.DeserializeObject<List<RoleData>>(json);
        }
        else listRoles = new List<RoleData>();

        filePath = Path.Combine(Application.persistentDataPath, "dicItems.json");
        if (File.Exists(filePath) == true)
        {
            string json = File.ReadAllText(filePath);
            dicItems = JsonConvert.DeserializeObject<Dictionary<string, List<ItemData>>>(json);
        }
        else dicItems = new Dictionary<string, List<ItemData>>();

        filePath = Path.Combine(Application.persistentDataPath, "dicMissions.json");
        if (File.Exists(filePath) == true)
        {
            string json = File.ReadAllText(filePath);
            dicMissions = JsonConvert.DeserializeObject<Dictionary<string, List<MissionData>>>(json);
        }
        else dicMissions = new Dictionary<string, List<MissionData>>();

    }

    public static DropDataInfo Drop(string dropId)
    {
        DropInfo dropInfo = StaticData.GetDropInfo(dropId);
        DropDataInfo dropDataInfo = GetDrop(dropInfo);
        //如果掉落内容ID为空，掉落失败
        if (string.IsNullOrEmpty(dropDataInfo.id))
        {
            Debug.Log("掉落 :" + null);
            return null;
        }


        switch (dropDataInfo.type)
        {
            case 0:
                for (int i = 0; i < dropDataInfo.num; i++)
                {
                    Drop(dropDataInfo.id);
                }
                break;
            case 1:
                return dropDataInfo;
        }
        return dropDataInfo;
    }

    public static void AddProp(string name, int num)
    {
        ItemInfo itemInfo = StaticData.GetItemInfo(name);
        if (itemInfo.stack > 1)
        {
            ItemData itemData = GetItemData(name);
            if (itemData != null && itemData.num < itemInfo.stack)//堆叠没到上限
            {
                itemData.num += num;
                if (itemData.num > itemInfo.stack)//超过上限
                {
                    num = itemData.num - itemInfo.stack;
                    itemData.num = itemInfo.stack;
                }
                else
                {
                    num = 0;
                }
            }
        }

        if (num > 0)
        {
            AddItemData(new ItemData()
            {
                id = Guid.NewGuid().ToString(),
                itemId = name,
                num = num,
            });
        }

        isItemChanged = true;
    }

    public static DropDataInfo GetDrop(DropInfo dropInfo)
    {
        int allWeight = 0;
        //将所有权重加起来获得总权重
        for (int i = 0; i < dropInfo.drops.Count; i++)
        {
            allWeight += dropInfo.drops[i].weight;
        }
        //随机
        int w = UnityEngine.Random.Range(0, allWeight);
        for (int i = 0; i < dropInfo.drops.Count; i++)
        {
            if (w < dropInfo.drops[i].weight)
            {
                return dropInfo.drops[i];
            }
            else
            {
                w -= dropInfo.drops[i].weight;
            }
        }

        return null;
    }

    public static ItemData GetItemData(string id)
    {
        List<ItemData> itemDatas = dicItems[listRoles[_curRoleIndex].id];
        for (int i = 0; i < itemDatas.Count; i++)
        {
            if (itemDatas[i].itemId == id || itemDatas[i].id == id)
            {
                return itemDatas[i];
            }
        }
        return null;
    }

    public static void AddItemData(ItemData item)
    {
        List<ItemData> itemDatas = dicItems[listRoles[_curRoleIndex].id];
        itemDatas.Add(item);
    }

    internal static void Equip(string id)
    {
        ItemData itemData = GetItemData(id);
        if (itemData == null)
            return;
        ItemInfo itemInfo = itemData.GetItemInfo();
        if (itemInfo.type != 2)
            return;

        EquipInfo equipInfo = StaticData.GetEquipInfo(itemInfo.id);

        UnEquip(equipInfo.slot);

        _curRole.equips[equipInfo.slot] = equipInfo.id;
        RemoveItemData(itemData);

        for (int i = 0; i < equipInfo.attrs.Count; i++)
        {
            _curRole.ChangeAttr(equipInfo.attrs[i].attr, equipInfo.attrs[i].value);
        }
        GameData.isItemChanged = true;
    }

    internal static void UnEquip(int equipSlot)
    {
        if (_curRole.equips.ContainsKey(equipSlot) == false)
            return;

        if (_curRole.equips[equipSlot] != "")
        {
            EquipInfo equipInfo = StaticData.GetEquipInfo(_curRole.equips[equipSlot]);
            for (int i = 0; i < equipInfo.attrs.Count; i++)
            {
                _curRole.ChangeAttr(equipInfo.attrs[i].attr, -equipInfo.attrs[i].value);
            }

            AddItemData(new ItemData()
            {
                id = Guid.NewGuid().ToString(),
                itemId = _curRole.equips[equipSlot],
                num = 1
            });

        }
        _curRole.equips.Remove(equipSlot);
    }

    internal static void RemoveItemData(ItemData item)
    {
        dicItems[listRoles[_curRoleIndex].id].Remove(item);
    }
    public static int GetFinishMissionNum()
    {
        return listRoles[_curRoleIndex].finishMission;
    }

    public static int GetMissionNumMax()
    {
        return dicMissions.Count;
    }

    public static void GetMissions()
    {
        for (int i = 0; i < _curMission.Count; i++)
        {
            Debug.Log(_curMission[i].id + _curMission[i].isFinish);
        }

        List<MissionInfo> missions = StaticData.listMissionInfo;

        for (int i = 0; i < missions.Count; i++)
        {
            bool isTrigger = false; 
            if (_curMission.Count > 0)
            {
                for (int j = 0; j < _curMission.Count; j++)
                {
                    if (missions[i].id == _curMission[j].id)
                        isTrigger = true;
                }
            }

            if (isTrigger)
                continue;
            
            int v = 0;
            for (int k = 0; k < missions[i].unlock.Length; k++)
            {
                MissionData data = null;
                foreach (MissionData mission in _curMission)
                {
                    if (mission.id == missions[i].unlock[k])
                    {
                        data = mission;
                    }

                    if (data != null)
                    {
                        if (mission.isFinish == true)
                        {
                            v++;
                        }
                        break;
                    }
                }
            }

            if (v == missions[i].unlock.Length) _curMission.Add(new MissionData
            {
                id = missions[i].id,
            });
        }

        isMissionChanged = true;
    }

    public static MissionData GetMissionData(string id)
    {
        for (int i = 0; i < _curMission.Count; i++)
        {
            if (_curMission[i].id == id)
            {
                return _curMission[i];
            }
        }
        return null;
    }
    public static void AddMissionPrograss(int type, string value, int num)
    {
        for (int i = 0; i < _curMission.Count; i++)
        {
            if (_curMission[i].isFinish == false)
            {
                MissionInfo missionInfo = StaticData.GetMissionInfo(_curMission[i].id);

                if (missionInfo.type == type)
                {
                    if (missionInfo.value1 == value)
                    {
                        _curMission[i].progress += num;
                    }
                }
            }
        }
        isMissionProgressChanged = true;
    }

    internal static int GetMissionProgress(string id)
    {
        MissionInfo missionInfo = StaticData.GetMissionInfo(id);
        if (missionInfo.type == 1)
        {
            for (int i = 0; i < _curMission.Count; i++)
            {
                if (_curMission[i].id == id)
                {
                    return _curMission[i].progress;
                }
            }
        }
        else if (missionInfo.type == 2)
        {
            return GetPropNum(missionInfo.value1);
        }
        else if (missionInfo.type == 3)
        {
            return listRoles[_curRoleIndex].dungeonLevel;
        }
        return 0;
    }

    internal static void FinishMission(string id)
    {
        for (int i = 0; i < _curMission.Count; i++)
        {
            if (_curMission[i].id == id)
            {
                _curMission[i].isFinish = true;
            }
        }
        isMissionChanged = true;
    }

    public static int GetDungeonProgress()
    {
        return listRoles[_curRoleIndex].dungeonLevel;
    }

    public static int GetPropNum(string id)
    {
        List<ItemData> items = dicItems[listRoles[_curRoleIndex].id];

        for (int i = 0; i < items.Count; i++)
        {
            if (items[i].itemId == id)
            {
                return items[i].num;
            }
        }
        return 0;
    }

    public static List<ItemData> GetCurRoleItems()
    {
        List<ItemData> curRoleItems = dicItems[listRoles[_curRoleIndex].id];

        for (int i = 0; i < curRoleItems.Count; i++)
        {
            ItemInfo itemInfo = curRoleItems[i].GetItemInfo();
            if (i > 0)
            {
                ItemInfo itemInfo1 = curRoleItems[i - 1].GetItemInfo();
                if (itemInfo.type == 2 && itemInfo1.type != 2)
                {
                    ItemData item = curRoleItems[i - 1];
                    curRoleItems[i - 1] = curRoleItems[i];
                    curRoleItems[i] = item;
                }
            }
        }

        return curRoleItems;
    }
}

